package org.bwapi.unit.server;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import org.bwapi.bridge.BridgeBot;

/**
 * Implementation of {@link BwapiBridgeBotServer}
 * 
 * @author Chad Retz
 */
@SuppressWarnings("serial")
public class BwapiBridgeBotServerImpl extends UnicastRemoteObject
		implements BwapiBridgeBotServer {
	
	private static final Registry registry;
	
	static {
		try {
			registry = LocateRegistry.createRegistry(PORT);
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	
	public static void startServer(Class<? extends BridgeBot> bridgeBotClass,
			BwapiBridgeBotServerCallback callback) throws Exception {
		new BwapiBridgeBotServerImpl(callback, bridgeBotClass);
	}
	
	private final BwapiBridgeBotServerCallback callback;
	private final Class<? extends BridgeBot> bridgeBotClass;
	
	private BwapiBridgeBotServerImpl( 
			BwapiBridgeBotServerCallback callback,
			Class<? extends BridgeBot> bridgeBotClass) throws RemoteException {
		this.callback = callback;
		this.bridgeBotClass = bridgeBotClass;
		registry.rebind(NAME, this);
	}
	
	@Override
	public String getBridgeBotClass() throws RemoteException {
		return bridgeBotClass.getName();
	}
	
	private void unbind() throws RemoteException {
		//unbind...
		try {
			registry.unbind(NAME);
		} catch (NotBoundException e) {
			throw new RemoteException("Unable to unbind", e);
		}
	}

	@Override
	public void onEnd() throws RemoteException {
		unbind();
		callback.onEnd();
	}

	@Override
	public void onError(Throwable throwable) throws RemoteException {
		unbind();
		callback.onFailure(throwable);
	}

}
